﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting;
using TeamDev.SDK;
using TDB.Services;
using TDB.DBInternals;
using System.ServiceModel;
using TDB.Communication;

namespace TDB
{
  internal static class Server
  {
    private static System.Threading.AutoResetEvent StopRequested = new System.Threading.AutoResetEvent(false);
    private static System.ServiceModel.ServiceHost WcfHost = null;
    private static IChannel _currentChannel = null;

    //private static Dictionary<string, ObjectsStore> Stores = new Dictionary<string, ObjectsStore>();

    static Server()
    {
      EventLogWriter.EventDefaultSourceName = "TDB";
      AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    }

    static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
      return AssemblyStore.Get(args.Name);
    }

    public static void Start()
    {
      Configuration.Load();

      RemotingConfiguration.ApplicationName = Configuration.Current.ServerName;

      EventLogWriter.LogMessage("Server starting ...", System.Diagnostics.EventLogEntryType.Information);
      EventLogWriter.LogMessage("Init journaling ...", System.Diagnostics.EventLogEntryType.Information);

      // Init Journaling Agent.
      if (Journaling.InitJournaling())
      {
        EventLogWriter.LogMessage("Registering communication channels ...", System.Diagnostics.EventLogEntryType.Information);

        //var sh = new ServiceHost(typeof(DataService), new Uri(""));
        //sh.Open();

        // Open DB Communication Channel with Remoting
        //ChannelServices.RegisterChannel(_currentChannel = new TcpChannel(5897), false);
        //RemotingConfiguration.RegisterWellKnownServiceType(typeof(Store), Configuration.Current.ServerName, WellKnownObjectMode.SingleCall);

        // Start DB Cleaning Agent
        Cleaning.Start();

        EventLogWriter.LogMessage("Server successfully started.", System.Diagnostics.EventLogEntryType.Information);
      }
    }

    public static void Stop()
    {
      Configuration.Save();

      EventLogWriter.LogMessage("Server shutting down ...", System.Diagnostics.EventLogEntryType.Information);

      EventLogWriter.LogMessage("Unregistering communication channels ...", System.Diagnostics.EventLogEntryType.Information);

      // Close Server Communication Channel
      ChannelServices.UnregisterChannel(_currentChannel);

      // Stop DB Cleaning Agent
      Cleaning.Stop();

      EventLogWriter.LogMessage("Stop journaling ...", System.Diagnostics.EventLogEntryType.Information);
      // Close Journaling Agent
      Journaling.StopJournaling();

      //foreach (var ss in Stores.Values)
      //  ss.Close();

      EventLogWriter.LogMessage("Shutdown completed!", System.Diagnostics.EventLogEntryType.Information);
      // Send shutdown completed message to stop main thread. 
      StopRequested.Set();
    }

    public static void WaitForExit()
    {
      StopRequested.WaitOne();
    }

    //public static string[] GetStores()
    //{
    //  return Stores.Keys.ToArray();
    //}

    //public static ObjectsStore GetStore(string name)
    //{
    //  if (Stores.ContainsKey(name))
    //    return Stores[name];
    //  return null;
    //}

    //internal static void CreateStore(string name)
    //{
    //  if (!Stores.ContainsKey(name))
    //  {
    //    Configuration.Current.DataBases.Add(name);
    //    var newstore = new ObjectsStore();

    //    newstore.StoreName = name;
    //    newstore.Journaling.DataBaseName = name;
    //    newstore.Journaling.Init();

    //    Stores.Add(name, newstore);

    //    Configuration.Save();
    //  }
    //}

    internal static void EmergencyShutdown()
    {
      EventLogWriter.LogMessage("Server emergency shutdown started.", System.Diagnostics.EventLogEntryType.Error);
      Server.Stop();
    }
  }
}
